HAL SMARTCARD initialization and configuration functions migration

The goal of this page is to show how to migrate the initialization sequence using STM32CubeMX2:

  • Open STM32CubeMX2 SMARTCARD configuration panel.

  • Configure the SW layer HAL.

  • Configure the SMARTCARD main features.

  • Configure the advanced SMARTCARD features if needed.

  • Configure the SMARTCARD GPIO pins.

  • Configure the SMARTCARD DMA(s) if the application requires the SMARTCARD to be used in DMA mode.

  • Configure the NVIC if the application requires the SMARTCARD to be used in IT mode.

  • Generate the code.

Note

The configuration below might vary from a series to another.

HAL SMARTCARD configuration panel

Create a new project with STM32CubeMX2, start by enabling the USART instance as SMARTCARD, as shown in this example with the selected USART1, then start the initialization and the main configuration.

Project configuration panel

HAL SMARTCARD main features configuration

Configure the SMARTCARD main features.

SMARTCARD main feature configuration

HAL SMARTCARD advanced features configuration

Configure the advanced SMARTCARD features if needed.

SMARTCARD advanced feature configuration

GPIO configuration

Configure GPIO pins.

SMARTCARD GPIO configuration

DMA configuration

Configure the DMA for data reception as needed.

SMARTCARD DMA configuration

NVIC configuration

Configure the NVIC in case of an interrupt.

SMARTCARD NVIC configuration

Generated SMARTCARD initialization and de-initialization sequences

The SMARTCARD initialization sequence is generated in the mx_usart1_smartcard_init function in mx_usart1.c file under $YOUR_PROJECT_NAME$/$YOUR_PROJECT_NAME$_SW/generated/STM32Cube_CodeGen.

Related concepts:

STM32CubeMX2 Generated : SMARTCARD initialization and De-initialization sequence

Topic

HAL1 Code Snippet

HAL2 Code Snippet

Handle declaration

SMARTCARD_HandleTypeDef hsmartcard1;
DMA_HandleTypeDef hLPDMA1_CH1;
DMA_HandleTypeDef hLPDMA1_CH0;
hal_smartcard_handle_t hsmartcard1;
hal_dma_handle_t hLPDMA1_CH1;
hal_dma_handle_t hLPDMA1_CH0;

Initialization and configuration sequence

static void MX_USART1_SMARTCARD_Init(void)
{
    hsmartcard1.Instance = USART1;
    hsmartcard1.Init.BaudRate = 10752;
    hsmartcard1.Init.WordLength = SMARTCARD_WORDLENGTH_9B;
    hsmartcard1.Init.StopBits = SMARTCARD_STOPBITS_1_5;
    hsmartcard1.Init.Parity = SMARTCARD_PARITY_EVEN;
    hsmartcard1.Init.Mode = SMARTCARD_MODE_TX_RX;
    hsmartcard1.Init.CLKPolarity = SMARTCARD_POLARITY_LOW;
    hsmartcard1.Init.CLKPhase = SMARTCARD_PHASE_1EDGE;
    hsmartcard1.Init.CLKLastBit = SMARTCARD_LASTBIT_ENABLE;
    hsmartcard1.Init.OneBitSampling = SMARTCARD_ONE_BIT_SAMPLE_DISABLE;
    hsmartcard1.Init.Prescaler = 10;
    hsmartcard1.Init.GuardTime = 0;
    hsmartcard1.Init.NACKEnable = SMARTCARD_NACK_DISABLE;
    hsmartcard1.Init.TimeOutEnable = SMARTCARD_TIMEOUT_DISABLE;
    hsmartcard1.Init.BlockLength = 0;
    hsmartcard1.Init.AutoRetryCount = 0;
    hsmartcard1.Init.ClockPrescaler = SMARTCARD_PRESCALER_DIV2;
    hsmartcard1.AdvancedInit.AdvFeatureInit = SMARTCARD_ADVFEATURE_NO_INIT;

    if (HAL_SMARTCARD_Init(&hsmartcard1) != HAL_OK)
    {
      Error_Handler();
    }

    /* Fifo configuration */
    if (HAL_SMARTCARDEx_SetTxFifoThreshold(&hsmartcard1,
                                           SMARTCARD_TXFIFO_THRESHOLD_1_8) != HAL_OK)
    {
      Error_Handler();
    }
    if (HAL_SMARTCARDEx_SetRxFifoThreshold(&hsmartcard1,
                                           SMARTCARD_RXFIFO_THRESHOLD_1_8) != HAL_OK)
    {
      Error_Handler();
    }
    if (HAL_SMARTCARDEx_EnableFifoMode(&hsmartcard1) != HAL_OK)
    {
      Error_Handler();
    }
 }

void HAL_SMARTCARD_MspInit(SMARTCARD_HandleTypeDef* hsmartcard)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
  if(hsmartcard->Instance==SMARTCARD1)
  {
    __HAL_RCC_USART1_CLK_ENABLE();

    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1;
    PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
    {
      Error_Handler();
    }


    /*GPIO*/
    __HAL_RCC_GPIOA_CLK_ENABLE();



    /* SMARTCARD1 CK Configuration */
    GPIO_InitStruct.Pin = GPIO_PIN_8;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF7_SMARTCARD1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* SMARTCARD1 TX Configuration */
    GPIO_InitStruct.Pin = GPIO_PIN_12;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF6_SMARTCARD1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* SMARTCARD1 RX Configuration */
    GPIO_InitStruct.Pin = GPIO_PIN_1;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF8_SMARTCARD1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);


    /* Enable interrupt */
    HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(USART1_IRQn);


  /* Configure the DMA TX */
  __HAL_RCC_LPDMA1_CLK_ENABLE();

  hLPDMA1_CH0.Instance = LPDMA1_Channel0;
  hLPDMA1_CH0.Init.Request = LPDMA1_REQUEST_SMARTCARD1_TX;
  hLPDMA1_CH0.Init.Direction = DMA_MEMORY_TO_MEMORY;
  hLPDMA1_CH0.Init.SrcInc = DMA_SINC_FIXED;
  hLPDMA1_CH0.Init.DestInc = DMA_DINC_FIXED;
  hLPDMA1_CH0.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_BYTE;
  hLPDMA1_CH0.Init.DestDataWidth = DMA_DEST_DATAWIDTH_BYTE;
  hLPDMA1_CH0.Init.Priority = DMA_LOW_PRIORITY_LOW_WEIGHT;

  if (HAL_DMA_Init(&hLPDMA1_CH0) != HAL_OK)
  {
    Error_Handler();
  }








  /* Link the Transmit DMA handle to the SMARTCARD handle */
  __HAL_LINKDMA(hsmartcard1, hdmarx, LPDMA1_Channel0);


  /* Enable the interruption for LPDMA1_CH0 */
  HAL_NVIC_SetPriority(LPDMA1_Channel0_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(LPDMA1_Channel0_IRQn);

 /* Configure the DMA RX */
  hLPDMA1_CH1.Instance = LPDMA1_Channel1;
  hLPDMA1_CH1.Init.Request = LPDMA1_REQUEST_SMARTCARD1_RX;
  hLPDMA1_CH1.Init.Direction = DMA_MEMORY_TO_MEMORY;
  hLPDMA1_CH1.Init.SrcInc = DMA_SINC_FIXED;
  hLPDMA1_CH1.Init.DestInc = DMA_DINC_FIXED;
  hLPDMA1_CH1.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_BYTE;
  hLPDMA1_CH1.Init.DestDataWidth = DMA_DEST_DATAWIDTH_BYTE;
  hLPDMA1_CH1.Init.Priority = DMA_LOW_PRIORITY_LOW_WEIGHT;

  if (HAL_DMA_Init(&hLPDMA1_CH1) != HAL_OK)
  {
    Error_Handler();
  }












  /* Link the Transmit DMA handle to the SMARTCARD handle */
  __HAL_LINKDMA(hSMARTCARD4, hdmatx, LPDMA1_Channel1);





  HAL_NVIC_SetPriority(LPDMA1_Channel1_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(LPDMA1_Channel1_IRQn);
}
hal_smartcard_handle_t *mx_usart1_smartcard_init(void)
{
  hal_smartcard_config_t smartcard_config;

  smartcard_config.baud_rate = 10752U;
  smartcard_config.stop_bits = HAL_SMARTCARD_STOP_BIT_0_5;
  smartcard_config.first_bit = HAL_SMARTCARD_BIT_ORDER_LSB_FIRST;
  smartcard_config.parity = HAL_SMARTCARD_PARITY_ODD;
  smartcard_config.nack = HAL_SMARTCARD_NACK_DISABLE;
  smartcard_config.clock_prescaler = HAL_SMARTCARD_CLOCK_PRESC_DIV1;
  smartcard_config.sclk_prescaler = HAL_SMARTCARD_SCLK_PRESC_DIV2;
  smartcard_config.clock_output = HAL_SMARTCARD_CLOCK_OUTPUT_DISABLE;
  smartcard_config.clock_polarity = HAL_SMARTCARD_CLOCK_POLARITY_LOW;
  smartcard_config.clock_phase = HAL_SMARTCARD_CLOCK_PHASE_1_EDGE;
  smartcard_config.guard_time_etu = 0U;
  smartcard_config.auto_retry_count = 0U;

  if (HAL_SMARTCARD_Init(&hUSART1, HAL_SMARTCARD1) != HAL_OK)
  {
    return NULL;
  }

  if (HAL_SMARTCARD_SetConfig(&hUSART1, &smartcard_config) != HAL_OK)
  {
    return NULL;
  }

  /* Fifo configuration */
  if (HAL_SMARTCARD_SetTxFifoThreshold(&hUSART1,
                                       HAL_SMARTCARD_FIFO_THRESHOLD_1_8) != HAL_OK)
  {
    return NULL;
  }
  if (HAL_SMARTCARD_SetRxFifoThreshold(&hUSART1,
                                       HAL_SMARTCARD_FIFO_THRESHOLD_1_8) != HAL_OK)
  {
    return NULL;
  }

  if (HAL_SMARTCARD_EnableFifoMode(&hUSART1) != HAL_OK)
  {
    return NULL;
  }





  HAL_RCC_USART1_EnableClock();

  if (HAL_RCC_USART1_SetKernelClkSource(HAL_RCC_USART1_CLK_SRC_PCLK2) != HAL_OK)
  {
    return NULL;
  }





  /* GPIO */
  HAL_RCC_GPIOA_EnableClock();

  hal_gpio_config_t  gpio_config;

  /** PA8   --------->  SMARTCARD1_CK **/
  gpio_config.mode        = HAL_GPIO_MODE_ALTERNATE;
  gpio_config.output_type = HAL_GPIO_OUTPUT_PUSHPULL;
  gpio_config.pull        = HAL_GPIO_PULL_NO;
  gpio_config.speed       = HAL_GPIO_SPEED_FREQ_LOW;
  gpio_config.alternate   = HAL_GPIO_AF_7;
  HAL_GPIO_Init(HAL_GPIOA, HAL_GPIO_PIN_8 , &gpio_config);

  /** PA12  --------->  SMARTCARD1_TX  **/
  gpio_config.mode        = HAL_GPIO_MODE_ALTERNATE;
  gpio_config.output_type = HAL_GPIO_OUTPUT_PUSHPULL;
  gpio_config.pull        = HAL_GPIO_PULL_NO;
  gpio_config.speed       = HAL_GPIO_SPEED_FREQ_LOW;
  gpio_config.alternate   = HAL_GPIO_AF_6;
  HAL_GPIO_Init(HAL_GPIOA, HAL_GPIO_PIN_12, &gpio_config);

  /** PA1  --------->  SMARTCARD1_RX  **/
  gpio_config.mode        = HAL_GPIO_MODE_ALTERNATE;
  gpio_config.output_type = HAL_GPIO_OUTPUT_PUSHPULL;
  gpio_config.pull        = HAL_GPIO_PULL_NO;
  gpio_config.speed       = HAL_GPIO_SPEED_FREQ_LOW;
  gpio_config.alternate   = HAL_GPIO_AF_8;
  HAL_GPIO_Init(HAL_GPIOA, HAL_GPIO_PIN_1, &gpio_config);

  /* Enable interrupt */
  HAL_CORTEX_NVIC_SetPriority(USART1_IRQn,
                              HAL_CORTEX_NVIC_PREEMP_PRIORITY_0,
                              HAL_CORTEX_NVIC_SUB_PRIORITY_0);

  HAL_CORTEX_NVIC_EnableIRQ(USART1_IRQn);


  /* Configure the DMA TX */
  HAL_RCC_LPDMA1_EnableClock();

  hal_dma_direct_xfer_config_t xfer_cfg_usart1_tx_dma;
  xfer_cfg_usart1_tx_dma.request         = HAL_LPDMA1_REQUEST_SMARTCARD1_TX;
  xfer_cfg_usart1_tx_dma.direction       = HAL_DMA_DIRECTION_MEMORY_TO_PERIPH;
  xfer_cfg_usart1_tx_dma.src_inc         = HAL_DMA_SRC_ADDR_FIXED;
  xfer_cfg_usart1_tx_dma.dest_inc        = HAL_DMA_DEST_ADDR_FIXED;
  xfer_cfg_usart1_tx_dma.src_data_width  = HAL_DMA_SRC_DATA_WIDTH_BYTE;
  xfer_cfg_usart1_tx_dma.dest_data_width = HAL_DMA_DEST_DATA_WIDTH_BYTE;
  xfer_cfg_usart1_tx_dma.priority        = HAL_DMA_PRIORITY_LOW_WEIGHT_LOW;

  if (HAL_DMA_Init(&hLPDMA1_CH0, HAL_LPDMA1_CH0) != HAL_OK)
  {
    return NULL;
  }

  if (HAL_DMA_SetConfigPeriphDirectXfer(&hLPDMA1_CH0,
                                        &xfer_cfg_usart1_tx_dma) != HAL_OK)
  {
    return NULL;
  }

  /* Link the Transmit DMA handle to the SMARTCARD handle */
  if (HAL_SMARTCARD_SetTxDMA(&hsmartcard1, &hLPDMA1_CH0) != HAL_OK)
  {
    return NULL;
  }

    /* Enable the interruption for LPDMA1_CH0 */
  HAL_CORTEX_NVIC_SetPriority(LPDMA1_CH0_IRQn,
                              HAL_CORTEX_NVIC_PREEMP_PRIORITY_0,
                              HAL_CORTEX_NVIC_SUB_PRIORITY_0);

  HAL_CORTEX_NVIC_EnableIRQ(LPDMA1_CH0_IRQn);

  /* Configure the DMA RX */
  hal_dma_direct_xfer_config_t xfer_cfg_usart1_rx_dma;
  xfer_cfg_usart1_rx_dma.request         = HAL_LPDMA1_REQUEST_SMARTCARD1_RX;
  xfer_cfg_usart1_rx_dma.direction       = HAL_DMA_DIRECTION_PERIPH_TO_MEMORY;
  xfer_cfg_usart1_rx_dma.src_inc         = HAL_DMA_SRC_ADDR_FIXED;
  xfer_cfg_usart1_rx_dma.dest_inc        = HAL_DMA_DEST_ADDR_FIXED;
  xfer_cfg_usart1_rx_dma.src_data_width  = HAL_DMA_SRC_DATA_WIDTH_BYTE;
  xfer_cfg_usart1_rx_dma.dest_data_width = HAL_DMA_DEST_DATA_WIDTH_BYTE;
  xfer_cfg_usart1_rx_dma.priority        = HAL_DMA_PRIORITY_LOW_WEIGHT_LOW;

  if (HAL_DMA_Init(&hLPDMA1_CH1, HAL_LPDMA1_CH1) != HAL_OK)
  {
    return NULL;
  }

  if (HAL_DMA_SetConfigPeriphDirectXfer(&hLPDMA1_CH1, &xfer_cfg_usart1_rx_dma) != HAL_OK)
  {
    return NULL;
  }

  /* Link the Transmit DMA handle to the SMARTCARD handle */
  if (HAL_SMARTCARD_SetRxDMA(&hsmartcard1, &hLPDMA1_CH1) != HAL_OK)
  {
    return NULL;
  }

  /* Enable the interruption for LPDMA1_CH1 */
  HAL_CORTEX_NVIC_SetPriority(LPDMA1_CH1_IRQn,
                               HAL_CORTEX_NVIC_PREEMP_PRIORITY_0,
                               HAL_CORTEX_NVIC_SUB_PRIORITY_0);
  HAL_CORTEX_NVIC_EnableIRQ(LPDMA1_CH1_IRQn);

  return &hsmartcard1;
}

Deinitialization sequence

void HAL_SMARTCARD_MspDeInit(SMARTCARD_HandleTypeDef* hsmartcard)
{
  if(hsmartcard->Instance == USART1)
  {
    /* Disable USART1 interrupt */
    HAL_NVIC_DisableIRQ(USART1_IRQn);


    /* Disable USART1 clock */
    __HAL_RCC_USART1_CLK_DISABLE();

    /* Deinitialize GPIO pins for SMARTCARD1 TX,RX and CK */
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_1); // TX

    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_12); // RX


    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_8);  // CK

    /* De-initialize the DMA channels for RX and TX */

      HAL_DMA_DeInit(hsmartcard->hdmarx);

      HAL_DMA_DeInit(hsmartcard->hdmatx);


    /* Disable the DMA interrupts */
    HAL_NVIC_DisableIRQ(LPDMA1_Channel0_IRQn);

    HAL_NVIC_DisableIRQ(LPDMA1_Channel1_IRQn);
  }
}
void mx_usart1_smartcard_deinit(void)
{
  /* Disable interrupt */
  HAL_CORTEX_NVIC_DisableIRQ(LPDMA1_CH1_IRQn);
  (void)HAL_SMARTCARD_DeInit(&hsmartcard1);

  HAL_RCC_USART1_Reset();

  HAL_RCC_USART1_DisableClock();

  /* Deinitialization of USART1: USART1_CK  */
  HAL_GPIO_DeInit(HAL_GPIOA, HAL_GPIO_PIN_8);

  /* Deinitialization of USART1: USART1_TX  */
  HAL_GPIO_DeInit(HAL_GPIOA, HAL_GPIO_PIN_12);

  /* Deinitialization of USART1: USART1_RX  */
  HAL_GPIO_DeInit(HAL_GPIOA, HAL_GPIO_PIN_1);

  /* De-initialize the DMA channel */
  HAL_DMA_DeInit(&hLPDMA1_CH0);

  /* Disable the interruption for DMA */
  HAL_CORTEX_NVIC_DisableIRQ(LPDMA1_CH0_IRQn);

  /* De-initialize the DMA channel */
  HAL_DMA_DeInit(&hLPDMA1_CH1);

  /* Disable the interruption for DMA */
  HAL_CORTEX_NVIC_DisableIRQ(LPDMA1_CH1_IRQn);

}

IRQ handle function

void USART1_IRQHandler(void)
{
  HAL_SMARTCARD_IRQHandler(&hsmartcard1);
}

void LPDMA1_CH0_IRQHandler(void)
{
  HAL_DMA_IRQHandler(&hLPDMA1_CH0);
}

void LPDMA1_CH0_IRQHandler(void)
{
  HAL_DMA_IRQHandler(&hLPDMA1_CH0);
}
void USART1_IRQHandler(void)
{
  HAL_SMARTCARD_IRQHandler(&hsmartcard1);
}

void LPDMA1_CH0_IRQHandler(void)
{
  HAL_DMA_IRQHandler(&hLPDMA1_CH0);
}

void LPDMA1_CH0_IRQHandler(void)
{
  HAL_DMA_IRQHandler(&hLPDMA1_CH0);
}